using System;
using System.Text;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using ManagedAPI;

namespace UnitTest.Derived
{
	/// <summary>
	/// Summary description for FileEntityTest
	/// </summary>
	[TestClass]
	public class FileEntityTest
	{
		public FileEntityTest()
		{

		}

		#region Additional test attributes
		//
		// You can use the following additional attributes as you write your tests:
		//
		// Use ClassInitialize to run code before running the first test in the class
		// [ClassInitialize()]
		// public static void MyClassInitialize(TestContext testContext) { }
		//
		// Use ClassCleanup to run code after all tests in a class have run
		// [ClassCleanup()]
		// public static void MyClassCleanup() { }
		//
		// Use TestInitialize to run code before running each test 
		private static bool mOpenResult;
		[TestInitialize()]
		public void MyTestInitialize()
		{
			mOpenResult = Database.Open(UnderstandGlobalData.GetFileName());
			Assert.IsTrue(mOpenResult);
		}
		//
		// Use TestCleanup to run code after each test has run
		[TestCleanup()]
		public void MyTestCleanup()
		{
			Database.Close();
			mOpenResult = false;
		}
		//
		#endregion

		[TestMethod]
		public void TestFileEntity()
		{
			FileEntity fileEnt = Database.LookupFileEntity("classes.h");
			Assert.AreEqual("classes.h", fileEnt.NameShort);
			Assert.IsTrue(fileEnt != null);

			ClassType[] classDefines = fileEnt.GetClassTypeDefinitions();
			Assert.AreEqual(5, classDefines.Length);
			Assert.IsTrue(classDefines != null);

			FileEntity fooUtil = Database.LookupFileEntity("foo_Util.h");
			Assert.IsTrue(fooUtil != null);
			Assert.AreEqual("foo_Util.h", fooUtil.NameShort);

			ClassType[] moreClasses = fooUtil.GetClassTypeDefinitions();
			Assert.IsTrue(moreClasses != null);
			Assert.AreEqual(4, moreClasses.Length);
			Entity mem = moreClasses[0];
			Assert.AreEqual("foo::Util::Memorizer", mem.NameLong);

			Entity[] funcs = fooUtil.GetFunctionDeclarations();
			Assert.IsTrue(funcs != null);
			Assert.AreEqual("foo::Util::GetNewMemory", funcs[0].NameLong);

			funcs = fooUtil.GetFunctionDefinitions();
			Assert.IsTrue(funcs != null);
			Assert.AreEqual(2, funcs.Length);

			FileEntity inline = Database.LookupFileEntity("foo_Util_inline.h");
			Assert.IsTrue(inline != null);
			funcs = inline.GetFunctionDefinitions();
			Assert.IsTrue(funcs != null);
			Assert.AreEqual("foo::Util::GetExistingMem", funcs[0].NameLong);
		}

		[TestMethod]
		public void TestFileEntityClassTypes()
		{
			FileEntity fileEnt = Database.LookupFileEntity("classes.h");
			Assert.AreEqual("classes.h", fileEnt.NameShort);
			Assert.IsTrue(fileEnt != null);

			ClassType[] classDefines = fileEnt.GetClassTypeDefinitions();
			Assert.IsTrue(classDefines != null);


			ClassType[] entClassDefines = fileEnt.GetClassTypeDefinitions();
			Assert.IsTrue(entClassDefines != null);

			for (int i = 0; i < classDefines.Length; i++)
			{
				Assert.AreEqual(classDefines[i].NameLong, entClassDefines[i].NameLong);
			}
		}

		[TestMethod]
		public void TestFileEntity_base_h()
		{
			FileEntity baseFile = Database.LookupFileEntity("base.h");

			ClassType[] classes = baseFile.GetClassTypeDefinitions();
			Assert.AreEqual(1, classes.Length);
			Assert.AreEqual("Base", classes[0].NameSimple);
			Assert.AreEqual("C Class Type", classes[0].KindName);

			Reference[] typedefs = baseFile.Refs("Define", "Typedef ~Member");
			Assert.AreEqual(3, typedefs.Length);
			Assert.AreEqual("BasePtr", typedefs[0].ThisEntity.NameSimple);
			Assert.AreEqual("BasePointer", typedefs[1].ThisEntity.NameSimple);
			Assert.AreEqual("PointerforBases", typedefs[2].ThisEntity.NameSimple);

			Reference basePtrRef = typedefs[0];
			Assert.AreEqual("C Typedef Type", basePtrRef.ThisEntity.KindName);
			Assert.AreEqual("C Typedef Type", basePtrRef.Kind.NameLong);

			Reference basePtrRefB = typedefs[1];
			Assert.AreEqual("C Typedef Type", basePtrRefB.ThisEntity.KindName);
			Assert.AreEqual("C Typedef Type", basePtrRefB.Kind.NameLong);

			Entity[] enums = baseFile.GetEnumDefintions();
			Assert.AreEqual(2, enums.Length);

			Assert.AreEqual("DaysOfWeek", enums[0].NameLong);
			Assert.AreEqual("C Enum Type", enums[0].KindName);
			Assert.AreEqual("Months", enums[1].NameLong);
			Assert.AreEqual("C Enum Type", enums[1].KindName);
		}

		[TestMethod]
		public void TestFileEntity_classes_h()
		{
			FileEntity classesFile = Database.LookupFileEntity("classes.h");

			ClassType[] classes = classesFile.GetClassTypeDefinitions();
			Assert.AreEqual(5, classes.Length);
			Assert.AreEqual("Derived", classes[0].NameSimple);
			Assert.AreEqual("Younger", classes[1].NameSimple);
			Assert.AreEqual("Older", classes[2].NameSimple);
			Assert.AreEqual("Mommy", classes[3].NameSimple);
			Assert.AreEqual("giffer", classes[4].NameSimple);

			// check the class declarations
			Reference[] classDecls = classesFile.Refs("Declare ~Define", "Classes");
			Assert.AreEqual(2, classDecls.Length);
			Assert.AreEqual("Older", classDecls[0].ThisEntity.NameShort);
			Assert.AreEqual("C Class Type", classDecls[0].Kind.NameLong);

			Assert.AreEqual("Mommy", classDecls[1].ThisEntity.NameShort);
			Assert.AreEqual("C Class Type", classDecls[1].Kind.NameLong);
		}
	}
}
